package com.qlshouyu.gateway.client;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qlshouyu.gateway.client.model.Application;
import com.qlshouyu.gateway.client.model.Service;
import org.apache.commons.lang3.StringUtils;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.List;

public class Bootgateway {

    private final static Logger LOGGER = LoggerFactory.getLogger(Bootgateway.class);

    private CloseableHttpClient client;
    private ObjectMapper objectMapper;

    public Bootgateway(CloseableHttpClient client) {
        this.client = client;
        this.objectMapper = new ObjectMapper();
    }

    /**
     * 创建应用
     *
     * @param application
     * @return
     */
    public Application createApplication(String serverAddr, Application application) {
        HttpPost httpPost = new HttpPost(serverAddr + "/api/gateway/v1/application");
        StringEntity stringEntity = new StringEntity(application.toString(),
                ContentType.APPLICATION_JSON);
        httpPost.setEntity(stringEntity);
        try (CloseableHttpResponse response = this.client.execute(httpPost)) {
            if (response.getCode() == 200) {
                HttpEntity entity = response.getEntity();
                Rsp<Application> rsp = this.objectMapper.readValue(entity.getContent(), new TypeReference<Rsp<Application>>() {
                });
                if (rsp.getCode() == 200) {
                    return rsp.getData();
                }
            }
            LOGGER.error("Create application error response code:{}  {}", response.getCode(), response.getReasonPhrase());
        } catch (IOException e) {
            LOGGER.error("Create application request error", e);
        }
        LOGGER.error("Create application error request:{}", serverAddr + "/api/gateway/v1/application");
        return null;
    }

    /**
     * 根据应用编码获取应用信息
     *
     * @param code
     * @return
     */
    public Application getApplicationByCode(String serverAddr, String code) {
        if (StringUtils.isEmpty(code)) {
            LOGGER.error("Application code can not be empty");
            throw new RuntimeException("Application code can not be empty");
        }
        HttpGet httpGet = new HttpGet(serverAddr + "/api/gateway/v1/application/" + code);
        try (CloseableHttpResponse response = this.client.execute(httpGet)) {
            if (response.getCode() == 200) {
                HttpEntity entity = response.getEntity();
                Rsp<Application> rsp = this.objectMapper.readValue(entity.getContent(), new TypeReference<Rsp<Application>>() {
                });
                if (rsp.getCode() == 200) {
                    return rsp.getData();
                }
            }
            LOGGER.error("Create application error response code:{}  {}", response.getCode(), response.getReasonPhrase());
        } catch (IOException e) {
            LOGGER.error("Create application request error", e);
        }
        LOGGER.error("Create application error request:{}", serverAddr + "/api/gateway/v1/application/" + code);
        return null;
    }

    /**
     * 获取可用服务列表
     *
     * @param serverAddr
     * @return
     */
    public List<Service> getServiceList(String serverAddr) {
        HttpGet httpGet = new HttpGet(serverAddr + "/api/gateway/v1/apiservice/list");
        try (CloseableHttpResponse response = this.client.execute(httpGet)) {
            if (response.getCode() == 200) {
                HttpEntity entity = response.getEntity();
                Rsp<List<Service>> rsp = this.objectMapper.readValue(entity.getContent(), new TypeReference<Rsp<List<Service>>>() {
                });
                if (rsp.getCode() == 200) {
                    return rsp.getData();
                }
            }
            LOGGER.warn("Create application error response code:{}  {}", response.getCode(), response.getReasonPhrase());
        } catch (IOException e) {
            LOGGER.warn("Create application request error", e);
        }
        LOGGER.warn("Create application error request:{}", serverAddr + "/api/gateway/v1/apiservice/list");
        return null;
    }
}
